/****************************************************************
 ** Product  :   HP Subscriber Network Application Policy
 ** Module   :   gr-manager
 ** Date: Apr 10, 2015               
 ** Author: Hua Zhen
 ** (C) Copyright 2015, Hewlett-Packard Company, All Rights Reserved.
 ** This software is the proprietary information of HP, Inc.  
 ** Use is subject to license terms.
 *****************************************************************
 ** Description:   
 **    Merge all status info of local and remote GR site. Show in console with YAML format.
 **    
 ****************************************************************/
package com.hp.snap.gr.action.impl;

import com.hp.snap.gr.exception.ActionException;
import com.hp.snap.gr.model.*;
import com.hp.snap.gr.model.jaxb.ActionType;
import com.hp.snap.gr.utils.Constants;
import com.hp.snap.gr.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

import java.io.LineNumberReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 
 * Merge all status of local and remote GR site. And show these status info in console with YAML format. These status
 * from action output include: SGM status, SGR status and SGS status.
 * 
 *     SGM status: deployment site name, role, status.
 *     SGS status: DB Instance Name, Running Mode, Running Status, DR Agent running status.
 *     SGR status: Export file name, file size.
 *     All of status above consist of local site and remote site.
 * 
 * There is no parameter can be configured in the action. From the action output get related status info.
 *     LOCAL_SGM_STATUS: local SGM status info.
 *     REMOTE_SGM_STATUS: remote SGM status info.
 *     Local_Deployment_Name: local deployment site name.
 *     REMOTE_Deployment_Name: remote deployment site name.
 *     Local_Role: local deployment site role.
 *     Remote_Role: remote deployment site role.
 *     LocalDBStatusInfo: local DB status info.
 *     RemoteDBStatusInfo: remote DB status info.
 *     _REPLICATOR_STATUS_INFO: local replicator status info
 *     _REPLICATOR_REMOTE_STATUS_INFO: remote replicator status info
 *     Local_monitorSS: local site monitor status.
 *     Remote_monitorSS: remote site monitor status.
 *   
 * <P>
 * Version: 3.3 <br>
 * Author: Hua Zhen Date: Apr 10, 2015
 * 
 * </P>
 * 
 **/
public class MergeStatusInfoActionHandler extends AbstractActionHandler {

    private static Logger logger = LoggerFactory.getLogger(MergeStatusInfoActionHandler.class);

    @Override
    public void execute(ActionType action,
                        Map<String, Object> actionPlanInputs,
                        Map<String, Object> actionPlanOutputs) throws ActionException {

        StatusInfo statusInfo = new StatusInfo();
        LocalDeploymentInfo localDeploymemtInfo = new LocalDeploymentInfo();
        RemoteDeploymentInfo remoteDeploymentInfo = new RemoteDeploymentInfo();

        StringBuffer statusMsg = new StringBuffer();
        if (actionPlanOutputs.get(Constants.STATUS_LOCAL_SGM) != null) {
            //statusMsg.append("Local GR status is: ").append(actionPlanOutputs.get(Constants.STATUS_LOCAL_SGM));
            statusMsg.append(actionPlanOutputs.get(Constants.STATUS_LOCAL_SGM));
            //statusInfo.setLocal_3_GRStatus(statusMsg.toString());
            localDeploymemtInfo.setLocal_3_GRStatus(statusMsg.toString());
        }


        if (actionPlanOutputs.get(Constants.STATUS_LOCAL_DEPLOYMENT_NAME) != null) {
            statusMsg = new StringBuffer();
            //statusMsg.append("Current deployment name is: ").append(actionPlanOutputs.get(Constants.STATUS_DEPLOYMENT_NAME));
            statusMsg.append(actionPlanOutputs.get(Constants.STATUS_LOCAL_DEPLOYMENT_NAME));
            //statusInfo.setLocal_1_deploymentName(statusMsg.toString());
            localDeploymemtInfo.setLocal_1_deploymentName(statusMsg.toString());
        }

        if (actionPlanOutputs.get(Constants.STATUS_REMOTE_DEPLOYMENT_NAME) != null) {
            statusMsg = new StringBuffer();
            //statusMsg.append("Current deployment name is: ").append(actionPlanOutputs.get(Constants.STATUS_DEPLOYMENT_NAME));
            statusMsg.append(actionPlanOutputs.get(Constants.STATUS_REMOTE_DEPLOYMENT_NAME));
            //statusInfo.setRemote_1_deploymentName(statusMsg.toString());
            remoteDeploymentInfo.setRemote_1_deploymentName(statusMsg.toString());
        }


        if (actionPlanOutputs.get(Constants.STATUS_LOCAL_ROLE) != null) {
            statusMsg = new StringBuffer();
            //statusMsg.append("Current deployment role is: ").append(actionPlanOutputs.get(Constants.STATUS_ROLE));
            statusMsg.append(actionPlanOutputs.get(Constants.STATUS_LOCAL_ROLE));
            //statusInfo.setLocal_2_deploymentRole(statusMsg.toString());
            localDeploymemtInfo.setLocal_2_deploymentRole(statusMsg.toString());
        }

        if (actionPlanOutputs.get(Constants.STATUS_REMOTE_ROLE) != null) {
            statusMsg = new StringBuffer();
            //statusMsg.append("Current deployment role is: ").append(actionPlanOutputs.get(Constants.STATUS_ROLE));
            statusMsg.append(actionPlanOutputs.get(Constants.STATUS_REMOTE_ROLE));
            //statusInfo.setRemote_2_deploymentRole(statusMsg.toString());
            remoteDeploymentInfo.setRemote_2_deploymentRole(statusMsg.toString());
        }


        if (actionPlanOutputs.get(Constants.DB_STATUS_INFO_LOCAL) != null) {
//            String dbStatusInfoJson = new Gson().toJson(actionPlanOutputs.get(Constants.DB_STATUS_INFO_LOCAL), Map.class);
            //Yaml yaml = new Yaml();
            //String dbStatusInfo = yaml.dump(actionPlanOutputs.get(Constants.DB_STATUS_INFO));
//            statusMsg = new StringBuffer();
            //statusMsg.append("SGS status is:").append(dbStatusInfoJson);
//            statusMsg.append(dbStatusInfoJson);
            Map<String, DBStatusInfo> dbStatusMap = (Map<String, DBStatusInfo>) actionPlanOutputs.get(Constants.DB_STATUS_INFO_LOCAL);
            List<DBStatusInfo> dbStatusLst = new ArrayList<DBStatusInfo>();
            for (String key : dbStatusMap.keySet()) {
                DBStatusInfo obj = dbStatusMap.get(key);
                dbStatusLst.add(obj);
            }
            //statusInfo.setLocal_4_SgsStatus(dbStatusLst);
            localDeploymemtInfo.setLocal_4_SgsStatus(dbStatusLst);
        }

        if (actionPlanOutputs.get(Constants.DB_STATUS_INFO_REMOTE) != null) {
            Map<String, DBStatusInfo> dbStatusMap = (Map<String, DBStatusInfo>) actionPlanOutputs.get(Constants.DB_STATUS_INFO_REMOTE);

            List<DBStatusInfo> dbStatusLst = new ArrayList<DBStatusInfo>();
            for (String key : dbStatusMap.keySet()) {
                DBStatusInfo obj = dbStatusMap.get(key);
                dbStatusLst.add(obj);
            }
            // statusInfo.setRemote_4_SgsStatus(dbStatusLst);
            remoteDeploymentInfo.setRemote_4_SgsStatus(dbStatusLst);
        }

        if (actionPlanOutputs.get(Constants.REPLICATOR_STATUS_INFO) != null) {
//        	statusMsg = new StringBuffer();
            //statusMsg.append("SGR status is:").append(actionPlanOutputs.get(Constants.LOCAL_SHELL_STDOUT));
//        	statusMsg.append(actionPlanOutputs.get(Constants.REPLICATOR_STATUS_INFO));
            //statusInfo.setT_1_sgrStatus((ReplicatorStatusInfo)actionPlanOutputs.get(Constants.REPLICATOR_STATUS_INFO));
            localDeploymemtInfo.setLocal_5_sgrStatus((ReplicatorStatusInfo) actionPlanOutputs.get(Constants.REPLICATOR_STATUS_INFO));
        }

        if (actionPlanOutputs.get(Constants.REPLICATOR_REMOTE_STATUS_INFO) != null) {
            remoteDeploymentInfo.setRemote_5_sgrStatus((ReplicatorStatusInfo) actionPlanOutputs.get(Constants.REPLICATOR_REMOTE_STATUS_INFO));
        }


        if (actionPlanOutputs.get(Constants.STATUS_LOCAL_MONITOR) != null) {
            statusMsg = new StringBuffer();
            //statusMsg.append("SGM Monitor status is:").append(actionPlanOutputs.get(Constants.STATUS_MONITOR));
            statusMsg.append(actionPlanOutputs.get(Constants.STATUS_LOCAL_MONITOR));
//        	statusInfo.setT_2_monitorStatus(statusMsg.toString());
            localDeploymemtInfo.setLocal_41_monitorStatus(statusMsg.toString());
        }

        if (actionPlanOutputs.get(Constants.STATUS_REMOTE_MONITOR) != null) {
            statusMsg = new StringBuffer();
            statusMsg.append(actionPlanOutputs.get(Constants.STATUS_REMOTE_MONITOR));
            remoteDeploymentInfo.setRemote_41_monitorStatus(statusMsg.toString());
        }

        if (actionPlanOutputs.get(Constants.STATUS_REMOTE_SGM) != null) {
            statusMsg = new StringBuffer();
            //statusMsg.append("Remote SGM status is:").append(actionPlanOutputs.get(Constants.STATUS_REMOTE_SGM));
            statusMsg.append(actionPlanOutputs.get(Constants.STATUS_REMOTE_SGM));
            //statusInfo.setRemote_3_GRStatus(statusMsg.toString());
            remoteDeploymentInfo.setRemote_3_GRStatus(statusMsg.toString());
        }
        try {
            //Utils.printStatusInfo(statusInfo);
            statusInfo.setLocal_deployment(localDeploymemtInfo);
            statusInfo.setRemote_deployment(remoteDeploymentInfo);
            StatusInfos statusInfos = new StatusInfos();
            statusInfos.getStatusInfos().add(statusInfo);
            Map<String, String> statusInfoLabel = Utils.getStatusInfoLabelMap();
            DumperOptions options = new DumperOptions();
            options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
            //options.setIndent(4);
            Yaml yaml = new Yaml(options);
            String x = yaml.dump(statusInfos);
            x = Utils.replaceString(x, statusInfoLabel);
            LineNumberReader r = new LineNumberReader(new StringReader(x));
            for (String line = r.readLine(); line != null; line = r.readLine()) {
                if (r.getLineNumber() == 1) continue;
                Constants.CONSOLE.info(line);
            }
        } catch (Exception e) {
            logger.error("print the status operation failed!!, exception is :{}", e.getMessage());
            new ActionException(e.getMessage(), e.getCause());
        }


    }

}
